import { Report } from '../service/ShellExec';
import {
  DEBUG,
  DEVICE_ID,
  APP_NAME,
  APP_VERSION,
  CHANNEL,
  OS_TYPE,
  DEVICE_BRAND,
  DEVICE_MODEL
} from '../constant';
import tracker from '../util/actionTracker';
import { requestError } from '../constant/events';
import { getRequestInfoWithId } from '../util/requestLifeCycle';
import { getUserInfo } from '../store/user';
import netSpeed from '../util/native/netSpeed';

const REPORT_PROD = 'https://stat.mifengxiaoban.com';
const REPORT_DEBUG = 'http://devstat.mifengxiaoban.com';

const ReportHost = DEBUG ? REPORT_DEBUG : REPORT_PROD;

export interface Param {
  needUserId?: boolean; // 请求参数是否添加userId
  needCommonParam?: boolean; // clientInfo是否需要添加公共参数
}

interface Params {
  [key: string]: any;
}

interface Request {
  url: string;
  data?: any;
  param?: Param;
}

const getCommonParam = (params: Params): object => {
  const { userId } = getUserInfo();
  return {
    clientInfo: {
      userId: params.userId || userId,
      appName: APP_NAME,
      appVersion: APP_VERSION,
      channelName: CHANNEL,
      deviceId: DEVICE_ID,
      platInfo: OS_TYPE
    }
  };
};

const commonParam = {
  osType: OS_TYPE,
  deviceBrand: DEVICE_BRAND,
  deviceModel: DEVICE_MODEL
};

export default ({ url, data = {}, param = {} }: Request): Promise<any> => {
  const { needUserId = true, needCommonParam = false } = param;

  let params = {
    ...data,
    ...getCommonParam(data)
  };

  if (needCommonParam) {
    params = {
      ...params,
      ...commonParam
    };
  }

  const { userId } = getUserInfo();

  if (needUserId) {
    params.userId = userId;
  }

  const startSt = +new Date();
  const startTotalBytes = netSpeed.getTotalRxBytes();
  const startAppBytes = netSpeed.getUidRxBytes(0);

  return Report(`${ReportHost}${url}`, data).catch((err): void => {
    try {
      const { error, requestId } = JSON.parse(err);
      const endSt = +new Date();
      const duration = endSt - startSt;
      const endTotalBytes = netSpeed.getTotalRxBytes();
      const endAppBytes = netSpeed.getUidRxBytes(0);
      const totalBytes = endTotalBytes - startTotalBytes;
      const appBytes = endAppBytes - startAppBytes;
      tracker.reportAction(requestError, {
        path: url,
        reason: JSON.stringify({
          error,
          duration,
          requestTime: getRequestInfoWithId(requestId),
          totalSpeed: netSpeed.getNetSpeed(totalBytes, duration),
          appSpeed: netSpeed.getNetSpeed(appBytes, duration)
        })
      });
    } catch (e) {
      tracker.reportAction(requestError, {
        path: 'json parse error report',
        reason: JSON.stringify({
          url,
          error: `${e}`,
          err: `${err}`
        })
      });
    }
  });
};
